<template>
  <el-table ref=table :data="treeData" v-bind="$attrs" :row-key="rowKey"
    >
    <el-table-column v-if="columns.length===0" width="150">
      <template slot-scope="scope">{{scope.$index}}</template>
    </el-table-column>
    <el-table-column
      v-else
      v-for="(column, index) in columns"
      :key="column.prop"
      :label="column.label"
      :width="column.width"
    >
      <template slot-scope="scope">
        <!--菜单选项-->
        <el-checkbox
          v-if="index==0"
          :indeterminate="scope.row.indeterminate"
          v-model="scope.row.checked"
          @change="handleCheckAllChange(scope.$index, scope.row)"
        >{{scope.row[column.prop]}}</el-checkbox>
        <!--按钮选项-->
        <template v-else>
          <template v-if="column.prop===optionsKey">
            <el-checkbox
              v-for="(option,index) in scope.row[optionsKey]"
              :label="option.id"
              :key="option.id"
              v-model="scope.row[optionsKey][index].checked"
              @change="handleOptionCheckedChange(scope.$index, scope.row,scope.row[optionsKey][index])"
            >{{option.label}}</el-checkbox>
          </template>
          <span v-else>{{scope.row[column.prop]}}</span>
        </template>
      </template>
    </el-table-column>
    <slot></slot>
  </el-table>
</template>

<script>
/**
  Auth: James Zhao
  Created: 2019/5/6
*/
import Vue from "vue";

export default {
  name: "authTreeTable",
  props: {
    data: {
      type: [Array, Object],
      required: true
    },
    optionsKey: {
      type: String,
      default: "options"
    },
    columns: {
      type: Array,
      default: () => []
    },
    rowKey: {
      type: String,
      default: "id"
    }
  },
  data () {
    return {
      parents: {}
    };
  },
  computed: {
    treeData: function() {
      return this.data;
    }
  },
  created() {
  },
  mounted(){
    this.initTable();
  },
  watch: {
      data(val) {
        this.$nextTick(()=>{
          this.initTable();
          })
      }
  },
  methods: {
    initTable(){
      let me = this;
      if (me.rowKey){
        me.initParent(me.data);
        me.data.forEach(row => {
						me.expandRow(row)
        });
      }
      me.data.forEach(row => {
        me.updateCheckStatus(row);
      });

    },
    initParent(data, parent = null) {
      let me = this;
      data.forEach(function(record) {
        if (parent) {
          me.parents[record[me.rowKey]]=parent;
        }
        if (record.children && record.children.length > 0) {
          me.initParent(record.children, record);
        }
      });
    },
    expandRow(row){
      let me = this;
      let store =  me.$refs.table.store;
      let rowId = row[me.rowKey];
      const node = store.states.treeData[rowId];
      if (!row.children || row.children.length==0)
        return;
      if (!node || !!node.expanded==!!row.expanded)
        return;
			if("boolean"!=typeof node.expanded)
				return;

      store.toggleTreeExpansion(rowId);
      if (row.children){
        row.children.forEach(child=>{
          this.expandRow(child)
        })
      }
    },
    getTopRow(row) {
      let parent = this.parents[row[this.rowKey]];
      if (parent)
        return this.getTopRow(parent);
      else
        return row;
    },
    handleOptionCheckedChange(index, row, opt) {
      let options = row[this.optionsKey];
      //第一个选项为基本权限项
      if (options && options.length>0) {
        //如果是第一个选项未勾选，则其他选择自动设置为未勾选状态
        if (opt[this.rowKey]==options[0][this.rowKey]){
          if(!opt.checked){
            options.forEach(option => {
              if (option.checked){
                option.checked=false
              }
            });
          }
        }
        else {
          options.forEach(option => {
            if (option.checked){
              options[0].checked=true
            }
          });
        }
      }
      this.updateCheckStatus(this.getTopRow(row));
    },
    handleCheckAllChange(index, row) {
      if (!row.checked) {
        //全选状态，清除选择
        this.clearChecked(row);
      } else {
        this.setChecked(row);
      }
      this.updateCheckStatus(this.getTopRow(row));
    },
    //清除一行
    clearChecked(row) {
      if (row[this.optionsKey]) {
        row[this.optionsKey].forEach(option => {
          option.checked = false;
        });
      }
      row.checked = false;
      row.indeterminate = false;
      if (row.children) {
        row.children.forEach(child => {
          this.clearChecked(child);
        });
      }
    },
    //全选一行
    setChecked(row) {
      if (row[this.optionsKey]) {
        row[this.optionsKey].forEach(option => {
          option.checked = true;
        });
      }
      if (row.children) {
        row.children.forEach(child => {
          this.setChecked(child);
        });
      }
      row.checked = true;
      row.indeterminate = false;
    },

    updateCheckStatus(row) {
      let checked = false;
      let indeterminate = false;
      if (row[this.optionsKey] && row[this.optionsKey].length > 0) {
        row[this.optionsKey].forEach(option => {
          if (option.checked) checked = true;
          else indeterminate = true;
        });
      } else {
        indeterminate = false;
        checked = false;
      }

      if (row.children) {
        row.children.forEach(childRow => {
          this.updateCheckStatus(childRow);
          //子行未选或半选，则父行设置为半选状态
          if (childRow.checked) {
            checked = true; //子行被选中时，父行标记为选中状态
            if (childRow.indeterminate) indeterminate = true;
          } else indeterminate = true;
        });
      }
      row.checked = checked;
      row.indeterminate = checked && indeterminate;
    }
  }
};
</script>
<style rel="stylesheet/css">
.el-table__body {
  text-align: left;
}
.el-table td {
    padding: 5px 0;
}
.el-dialog__body {
    padding: 10px 20px;
}
</style>

<style lang="scss" rel="stylesheet/scss" scoped>
table td {
  line-height: 26px;
}

</style>
